keras 소스분석 - fine-tune.py 발표용
2017년 12월 24일 일요일
오전 2:21
소스: git clone https://github.com/DeepLearningSandbox/DeepLearningSandbox
너무 쉬운걸 이야기 하더라도 이해해주시고,
쉬운 개념 같은데 이해가 안되시는 건 또한 언제든지 인터럽트해서 질문해주세요
1) 이미지넷 이라는 1.2 백만개, 1000 클래스
(=종류)의 데이터셋이
있다
2) 이걸로 VGG, GoogLeNet (=Inception), ResNet 등의 CNN 딥러닝 모델들을
학습시키는데는 많은 컴퓨팅 자원과 시간이 소요된다
- 무지막지한 CPU와 GPU들 + 2, 3주의
학습시간
3) Keras 에서는
이미 학습된 weight 들을 가진 이런 유명 CNN 모델들을
제공해준다
4) 재활용하자
- 위 이미지는 왼쪽에서 입력이 들어와 오른쪽 끝에서 예측하는 것으로 보면 되겠다.
- 여기서 Edges, Shapes 를 추려내는 부분은 재활용이 가능하다는 것이다.
- 맨 끝단만 재학습 시키면 Transfer learning, 여러 상황에 따라
조금 더 거슬러 올라가면 Fine-tune이 되겠다.
* 우리 예제는 일단
Transfer learning 을 통해 Classifier 를 훈련시킨 다음에, Fine-tuning 을 통해 조금 더 위쪽 레이어를 다듬어준다
(learning rate 중요)
- 소스를 단위별로 분석해봄 = 순서는 뒤죽박죽으로 해보겠음
- 결국 181 라인밖에 안되는 소스임
|
argparse 라는 녀석으로 쉽게
argument 를 설정할 수 있나보다
1) 최소한 --train_dir
과 --val_dir은 지정해줘야 한다 2) 최소한 지정한 두 path 가
실제로 존재해야 한다 train(args) 실행 실제
train은 아래와 같이 실행함
- python3 fine-tune.py --train_dir ~/kaggle-dogcat/train_dir/ --val_dir ~/kaggle-dogcat/val_dir/ - 데이터들은 아래와
같이 저장되어 있다. - train 용, validation 용으로 크게 구분하며 - cat, dog 폴더
이름 자체가 class 의 라벨이 되고 - 폴더 안에는 각각 cat, dog 이미지들이 들어있다
|
|
train을 위한 정보들 정리해둠
1) nb_train_samples - get_nb_files() 함수는 해당 디렉토리의 모든 파일 개수를 리턴해줌 (recursively) 2) nb_classes - glob.glob() 함수로 train_dir 아래의 파일또는 디렉토리의 개수를 리턴 - 따라서 cat, dog가 있으니 2개의
class 가 있다는 것임 3) nb_val_samples - get_nb_files()
함수는 해당 디렉토리의 모든 파일 개수를 리턴해줌 (recursively) 4) nb_epoch, batch_size 역시 argument 로
넘어온 값을 변수에 넣어둠 data
prep
- 데이터를 augmentation (=조금 만져서 개수 늘리기) 하기 위한
함수를 생성하는 것으로 보임 - 실제로 데이터가
늘어난다기 보다는 매 학습시마다 변형을 준다 1) train_datagen, test_datagen 두 함수를 동일하게 생성 2) 전처리 함수는 preprocess_input (인셉션v3 패키지에서 제공하는
듯) 3) augmentation 방법은 - 돌리기, 종횡으로 옮기기, 짜부라트리기,
확대하기, 수평으로 뒤집기 실제 데이터 생성하는 레시피 작성 1) 위에서 만든 전처리
함수 train_datagen, test_datagen 으로 2) train_dir, val_dir 에 있는 이미지들을 3) 해상도 299x299, 배치사이즈 32로 만들어서 실제로 돌리기 좋게
해둠 |
|
setup
model
1) 베이스가 되는 모델은 - imagenet 데이터셋으로 - InceptionV3 라는 CNN 모델을 train 한
weight를 가져온다 - 가장 마지막 (=top) 레이어는 가져오지 않는다. 이녀석은 FC layer 이다 2) 베이스를 기반으로 새로 만든 모델은 - base_model 에
이어붙인뒤 마지막 레이어가 nb_classes (= dog, cat = 2개) 인 모델 - add_new_last_layer() 함수는 (별도로
조금 자세히봐도 좋겠지만 일단) 1) base_model.out = 마지막으로 내보내는 값을 받아서 2) GlobalAveragePooling2D() 를 해준다음 3) Dense = FC 를
해준다. FC_SIZE = 1024개로 해줌 4) Dense = FC 를
한 번 더해주는데 이번에는 softmax 를 해서 예측하도록 한다 - 예측값은 predictions 에 넣어준다 5) 드디어, 새로운 모델을 만들어서, 그 모델을 리턴해주게 된다 *keras 2 버전에서 바뀐것들: https://github.com/keras-team/keras/releases/tag/2.0.0 Model() 함수에서 input → inputs output → outputs |
Keras 2에서 변경
|
transfer
learning
1) setup_to_transfer_learn()
함수 - base_model 인
인셉션의 모든 레이어들에 대해 - 추가 학습이 되지
않게 = weight 값 변하지 않게 설정 - optimizer, loss, metrics 를 설정 2) fit_generator()
함수 - 보통은 fit() 함수로 학습시키지만 - generator 로
생성한 데이터를 학습시킬때는 fit_generator() 함수로 학습시킨다 1) train 할
데이터를 생성하는건 train_generator 2) 몇 epoch 학습할지, epoch 마다의 데이터 개수 3) validate 할
데이터를 생성하는건 valitation_generator 4) valitation 데이터
개수 5) class_weight 는 아마도 class 들간의 데이터 개수 불균형에 대한 조정방법인듯 *keras 2 버전에서 바뀐것들: https://github.com/keras-team/keras/releases/tag/2.0.0 - samples_per_epoch → steps_per_epoch (=samples_per_epoch / batch_size) - nb_epoch → epochs - nb_val_samples → validation_steps |
Keras 2에서 변경
|
fine-tuning
- 일단 위에서 transfer learning 된 model을 가져와서 다시 학습한다 1) setup_to_finetune()
함수 - 172 레이어까지는
trainable = False, 즉 초기 레이어들은 여전히 학습시키지 말고 - 172 부터는 기존
인셉션 v3 레이어도 trainable = True - optimizer의 learning_rate, momentum 설정, loss, metrics
설정 2) 마찬가지로
fit_generator() 함수로 학습 *keras 2 버전에서 바뀐것들: https://github.com/keras-team/keras/releases/tag/2.0.0 - samples_per_epoch → steps_per_epoch (=samples_per_epoch / batch_size) - nb_epoch → epochs - nb_val_samples → validation_steps |
|
1) 여기까지 학습이 완료된 모델을 save 2) plot_training() - args.plot 은 따로 argument를
안넣었으니 실행안됨 - GCE에서 matplotlib을 쓰려면 어케하면 될까? |
|
1) 파라미터로 넘어온 디렉토리를 2) recursive 하게 돌면서 3) 전체 파일 개수를 리턴해준다 |
|
1) base_model.out = 마지막으로 내보내는 값을 받아서 2) GlobalAveragePooling2D() 를 해준다. 참고링크
CNN에서의 FC vs average pooling 3) Dense = FC 를 해준다.
activation function은 relu. FC_SIZE = 1024개로 해줌 4) Dense = FC 를 해준다.
activation function은 softmax 를 써서 확률이 나오도록 함 - 예측값은 predictions 에 넣어준다 - 예측값은 확률이니
모든 클래스의 예측값을 더해주면 1이 된다 5) 드디어, 새로운
모델을 만들어서, 그 모델을 리턴해주게 된다 *keras 2 버전에서 바뀐것들: https://github.com/keras-team/keras/releases/tag/2.0.0 line 54의 Model() 함수에서 input → inputs output → outputs |
|
1) base_model = 인셉션 v3 의
2) 모든 레이어의
trainable = False - 즉, 우리의 새로운 dog, cat dataset 으로 추가 학습이
일어나지 않도록 한다 3) optimizer, loss, metrics 를 설정한다 |
|
1) base_model = 인셉션 v3 의
2) 172 레이어부터는
trainable = True - 즉, 우리의 새로운 dog, cat dataset 으로 - 172 레이어 이후만
추가 학습이 일어나도록 한다 3) optimizer, loss, metrics 를 설정한다 |
|
matplotlib 으로 학습과정을 시각화 해주는 함수 1) 코드에서는 transfer
learning 은 생략하고 2) fine-tuning 부분만 보여주게 해두었다. - fine-tune.py 함수도 주피터에서 실행하면 되긴 하겠다 |
python3 fine-tune.py --train_dir ~/kaggle-dogcat/train_dir/
--val_dir ~/kaggle-dogcat/val_dir/
1) 데이터셋만 가져다두고, 실행시 옵션에 넣어주기만 하면 된다
2) 모델의 학습이 완료되면 (save 되면 model 명을 명시하지 않으면) inceptionv3-ft.model 라는 파일로
저장된다
*기존 keras 1소스 그대로 했을 경우 warning
*keras 2 버전에서 바뀐것들: https://github.com/keras-team/keras/releases/tag/2.0.0
Model() 함수
input → inputs
output → outputs
fit_generator() 함수
- samples_per_epoch → steps_per_epoch (=samples_per_epoch / batch_size)
- nb_epoch → epochs
- nb_val_samples → validation_steps
- Ctrl-z 로 나오면, 프로세스 자체가 종료된게 아니라 계속 메모리를 잡아먹어, 다양한
문제가 발생한 것으로 보임
에러1. Resource exhausted: OOM when allocating tensor with shape
에러2. Error in `python3': double free or corruption
Microsoft OneNote 2016에서 작성